
package de.swta.freezay.user.orderPanel;

import de.swta.freezay.database.JPAController;
import de.swta.freezay.database.dbEntities.Reservation;
import de.swta.freezay.database.dbEntities.Package;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.NumberFormatter;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;


/**
 * The OrderPanel displays a choosen package and a form which contains 
 * a dropdown-component to select the package (reservation)count.
 *
 * @author Christian Baeumer
 */
public final class OrderPanel extends Panel {

    /* A NumberFormatter to display the price in the right way */
    private static final NumberFormatter NUMBER_FORMATTER
            = new NumberFormatter(new DecimalFormat("####.##"));

    /* the "new" reservation entity */
    private Reservation reservation;
    

    /**
     * Constructor
     *
     * @param id the markupID
     * @param packageID the packageID
     * @param parent the parent modal window
     */
    public OrderPanel(String id, int packageID, final ModalWindow parent) {

        super (id);

        /* get the package from db */
        final Package p
                = JPAController.PackageJpaController.findPackage(packageID);

        /* create a new reservation */
        reservation = new Reservation();

        /* add a simplified packageview */
        add(new OrderPackageView("packageView", p));

        /* init the form component */
        initForm(p, parent);
    }


   
    /**
     * Initialize the form component
     *
     * @param p package to order
     * @param parent the parent modal window
     */
    private void initForm(final Package p, final ModalWindow parent) {

        /* add a new confirmation dialog */
        final ModalWindow w = new ModalWindow("confirmation");
        add(w);

        /* create the form */
        Form form = new Form("orderForm");
        add(form);

        /* create the count label */
        form.add(new Label("label", "Anzahl: "));
        /* create the price label */
        final Label price = new Label("Price", "0 €");
        price.setOutputMarkupId(true);
        form.add(price);

        /* initialize the list for the dropdown component */
        final List<Integer> choices = new ArrayList<Integer>();
        /* availablePackageCount = packageCount - reservedPackages */
        final int pCount = p.getAvailableCount();
        /* fill the list with values */
        for (int i = 1; i <= pCount; i++) {
            choices.add(i);
        }
      
        /* create a model for the choices */
        IModel<List<? extends Integer>> modelChoices
                = new AbstractReadOnlyModel<List<? extends Integer>>() {
            @Override
            public List<Integer> getObject() {
                return choices;
            }
        };

        /* create a propery model for a reservation (the choosen dropdown-value
         * changes the package count with this model) */
        final PropertyModel<Integer> choicePorpertyModel
            = new PropertyModel<Integer>(reservation, "packagecount");

        /* create the dropdown component */
        DropDownChoice<Integer> choice = new DropDownChoice<Integer>(
                "reservationCount", choicePorpertyModel, modelChoices);
        choice.setNullValid(false);
        choice.setRequired(true);
        choice.setModelObject(choices.get(0));

        /* initialize the price component */
        updatePrice(p, choicePorpertyModel, price);

        /* add some ajax behavior to update other labels */
        choice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
            // <editor-fold defaultstate="collapsed" desc="update behaviour">
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                /* update price */
                updatePrice(p, choicePorpertyModel, price);
                target.addComponent(price);
            }
            // </editor-fold>
        });

        form.add(choice);

        /* add an order link */
        form.add(new AjaxLink("order") {
            // <editor-fold defaultstate="collapsed" desc="order behaviour">
            @Override
            public void onClick(AjaxRequestTarget target) {
                 /* create a new reservation package */
                reservation.setPackage1(p);
                /* create the validity for this reservation */
                Calendar c = Calendar.getInstance();
                c.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH) + 4);
                /* and store it */
                reservation.setValidity(c.getTime());

                try {
                   JPAController.ReservationJpaController.create(reservation);
                } catch (Exception ex) {
                    Logger.getLogger(OrderPanel.class.getName()).log(
                            Level.SEVERE, null, ex);
                }

                w.setContent(new OrderConfirmation(w.getContentId(), reservation));
                w.show(target);
                w.setCloseButtonCallback(new ModalWindow.CloseButtonCallback() {
                    public boolean onCloseButtonClicked(AjaxRequestTarget target1) {
                        parent.close(target1);
                        return true;
                    }
                });
            }

            // </editor-fold>
        });

        /* add a cancel link */
        form.add(new AjaxLink("cancel") {
            // <editor-fold defaultstate="collapsed" desc="cancel behaviour">
            @Override
            public void onClick(AjaxRequestTarget target) {
                /* close window on cancel */
                parent.close(target);
            }
            // </editor-fold>
        });

    }

    /**
     * Updates the price component
     *
     * @param p the package
     * @param choicePorpertyModel the property model
     * @param price the price component to update
     */
    private final void updatePrice(final Package p,
            final PropertyModel<Integer> choicePorpertyModel,
            final Label price) {

        double packagePrice = p.getPrice()
                        * choicePorpertyModel.getObject();
        try {
            price.setDefaultModelObject(""
                    + NUMBER_FORMATTER.valueToString(packagePrice)
                    + " €");
        } catch (ParseException ex) {
            Logger.getLogger(OrderPanel.class.getName()).log(
                    Level.SEVERE, null, ex);
        }
    }

}
